package net.windward.RoboRally.api;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

public class Info {
   
    GameMap map;
    Player you;
    java.util.List<Player> allPlayers;
    java.util.List<Card> cards;
   
    int numPlayers = allPlayers.size();
   
    String[] allPInfo = new String[6];

           
    public Info(GameMap map, Player you, java.util.List<Player> allPlayers, java.util.List<Card> cards){
        this.map = map;
        this.you = you;
        this.allPlayers = allPlayers;
        this.cards = cards;
    }
   
   
    public GameMap getMap(){return map;}
    public Player getYou(){return you;}
    public java.util.List<Player> getPlayers(){return allPlayers;}
    public java.util.List<Card> getCards(){return cards;}
   

   
    //gives you the id, cards, lives, damage, archive, and flag info in a String array
    public String[] quickGlance(Player p){
        Integer lives = p.getLives();
        Integer damage = p.getDamage();
       
        int f = 0;
        List<FlagState> fs = p.getFlagStates();
        for(int i = 0; i < fs.size(); i++){
            if(fs.get(i).getTouched()){
                f++;
            }
        }
        Integer flags = f; //number of flags touched
       
        allPInfo[0] = p.getGuid(); //id
        allPInfo[1] = p.getCards().toString(); //cards
        allPInfo[2] = lives.toString(); //lives
        allPInfo[3] = damage.toString(); //damage
        allPInfo[4] = p.getArchive().toString(); //entry point
        allPInfo[5] = flags.toString(); //flags collected
        allPInfo[6] = p.getPowerMode().toString(); //power mode
        allPInfo[7] = p.getMode().toString(); //mode   
       
        return allPInfo;
       
    }
   
    //return the locations of all players
    public BoardLocation[] getPLocations(){
        BoardLocation[] locations = new BoardLocation[numPlayers];
        for(int i = 0; i < numPlayers; i++){
            locations[i] = allPlayers.get(i).getRobot().getLocation(); //can use getMapPosition to get position as point
        }
        return locations;
    }
   
    //return true if the point is next to an indicated object
    //same integer legend as getStuff()
    public boolean nextToStuff(Point p, int i) {
        Point nPoint = new Point(p.x,p.y+1);
        Point ePoint = new Point(p.x+1,p.y);
        Point sPoint = new Point(p.x,p.y-1);
        Point wPoint = new Point(p.x-1,p.y);
      
        for (Point object : getStuff(i)) {
            if(nPoint.equals(object) || ePoint.equals(object) || sPoint.equals(object) || wPoint.equals(object)){
                return true;
            }
        }
        return false;
    }
   
    //returns the edges of the playing field
    public ArrayList<Point> getEdges(){
       
    ArrayList<Point> points = new ArrayList<Point>();
   
        for(int i = 0; i < map.getHeight(); i++){
            for(int j = 0; j < map.getWidth(); j++){
                if(i == 0 || j == 0 || i == map.getHeight() || j == map.getWidth()){
                    points.add(new Point(i,j));
                }
            }
        }   
        return points;
    }
    
    //return the locations of all one kind of object
    //0 is Normal
    //1 is Conveyor Belt
    //2 is Clockwise Gear
    //3 is Counter-Clockwise  Gear
    //4 is Repair Point
    //5 is Flag
    //6 is Pit
    public ArrayList<Point> getStuff(int i){
       
        MapSquare[][] wholeMap = new MapSquare[map.getHeight()][map.getWidth()];
        ArrayList<Point> position = new ArrayList<Point>();
       
        for(int j = 0; j < map.getHeight(); j++){
            for(int k = 0; k < map.getWidth(); k++){
                if(wholeMap[j][k].getType().getValue() == i){
                    Point target = new Point(j,k);
                    position.add(target);
                }
            }
    }       
        return position;
    }
       
    public boolean nextToPit(Point p) {
        if(nextToStuff(p, 6) || onEdge(p)) return true;
        return false;
    }
   
    //returns true if the point is one the edge, false otherwise
    public boolean onEdge(Point p){
        for(Point x : getEdges()){
            if (p.equals(x)) return true;
        }   
        return false;
    }
    
  //returns the next flag
    public BoardLocation nextFlag(){
       
        int f = 0;  //number of flags you have touched
       
        List<FlagState> fs = getYou().getFlagStates();
        for(int i = 0; i < fs.size(); i++){
            if(fs.get(i).getTouched()){
                f++;
            }
        }
       
        Point[] flagLoc = map.getFlags();

        if(f == 0) return new BoardLocation(flagLoc[0], MapSquare.DIRECTION.NORTH);
        if(f == 1) return new BoardLocation(flagLoc[1], MapSquare.DIRECTION.NORTH);
        if(f == 2) return new BoardLocation(flagLoc[2], MapSquare.DIRECTION.NORTH);
        return null;
    }
}